// BBoxesInput.js
import { setFObjectEditable, newRectFObject } from '@/js/utils/FabricControls';
import { getPointsFromBBox, getPointsLT, getPointsRB } from '@/js/utils/geomUtils';
import { getImageCoords, getCanvasCoords } from '@/js/utils/imageUtils';

// 检测任务的标注结果
export default class BBoxesInput {
    constructor(initialBBoxes = []) {
        this.tools_callback = {
            rect: this.rectToolCallback.bind(this)
        };

        // 存储rects的数据
        this.rects_geom = [];

        // 定义默认工具
        this.tools = ['pointer', 'rect'];
        this.mode = 'rect';

        // 初始化时根据传入的二维数组创建geom对象
        this.initialBBoxes = initialBBoxes;
    }

    // 在bindCanvas方法中添加初始化逻辑
    bindCanvas(canvas, image, label_tools) {
        // 绑定canvas  
        this.canvas = canvas;
        this.image = image;

        // 初始化geom对象
        if (this.initialBBoxes.length > 0) {
            let bboxes = this.initialBBoxes.map(bbox => {
                return {
                    left: bbox[0],
                    top: bbox[1],
                    width: bbox[2],
                    height: bbox[3]
                }
            });
            let canvas_bboxes = bboxes.map(bbox => {
                let points = [
                    { x: bbox.left, y: bbox.top }, // 左上
                    { x: bbox.left + bbox.width, y: bbox.top + bbox.height } // 右下
                ];
                return getCanvasCoords(this.image, points);
            });
            console.log('BBoxesInput::bindCanvas canvas_bboxes = ', canvas_bboxes);
            for (let i = 0; i < canvas_bboxes.length; i++) {
                let bbox_geom = this.paintBBox({
                    left: canvas_bboxes[i][0].x,
                    top: canvas_bboxes[i][0].y,
                    width: canvas_bboxes[i][1].x - canvas_bboxes[i][0].x,
                    height: canvas_bboxes[i][1].y - canvas_bboxes[i][0].y
                });
                if (bbox_geom) {
                    this.rects_geom.push(bbox_geom);
                    this.canvas.add(bbox_geom);
                }
            }
        }

        if (label_tools) {
            for (let tool_name in this.tools_callback) {
                let tool = label_tools[tool_name];
                let callback = this.tools_callback[tool_name];
                if (tool) {
                    tool.setCallback(callback);
                }
            }
        }

        // 刷新显示
        this.canvas.requestRenderAll();
        return true;
    }

    paintBBox(rect_coord) {
        // console.log('paintBBox label = ', label);
        if (!this.image) {
            return;
        }

        let rect_geom = newRectFObject(this.rects_geom.length, rect_coord);
        rect_geom.set({ selectable: false, evented: false });
        this.registerObjectEvents(rect_geom);
        return rect_geom;
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // 工具回调函数，更新外部UI显示
    rectToolCallback(rect) {
        // console.log('LabelDetection::rectToolCallback rect = ', rect, ' this = ', this);
        if (rect) {
            let rect_geom = this.paintBBox(rect);
            this.rects_geom.push(rect_geom);
            rect_geom && this.canvas.add(rect_geom);
        }
    }

    // 注册事件
    registerObjectEvents(object) {
        object.on('selected', this.onSelected.bind(this));
        object.on('modified', this.onModified.bind(this));
    }

    onSelected(event) {
        console.log(`onSelected event = `, event);
        if (event.target) {
            this.selectLabel(event.target.label_id, event.target);
        }
    }

    onModified(event) {
        console.log(`onModified event = `, event);
    }

    selectLabel(label_id, target = null) {
        console.log(`selectLabel label_id = ${label_id}, target = `, target);
        // 在canvas中选择标签对象
        if (!(label_id in this.points_geom)) {
            return;
        }

        // 放置待选择的对象
        setFObjectEditable(target);
        this.canvas.setActiveObject(target);
        this.canvas.requestRenderAll();
    }

    deleteSelection() {
        // 删除选中的对象
        let activeObject = this.canvas.getActiveObject();
        // console.log(`deleteSelection activeObject = `, activeObject);
        if (activeObject) {
            // 从points_geom中移除对应的元素
            const index = this.rects_geom.findIndex(p => p === activeObject);
            if (index !== -1) {
                this.rects_geom.splice(index, 1);
            }

            // 从canvas中移除对象
            this.canvas.remove(activeObject);
            this.canvas.requestRenderAll();
        }
    }

    getBBoxes() {
        let bboxes = this.rects_geom.map(rect => {
            // 将矩形转换为四个点的坐标
            return [
                { x: rect.left, y: rect.top }, // 左上
                { x: rect.left + rect.width, y: rect.top }, // 右上
                { x: rect.left + rect.width, y: rect.top + rect.height }, // 右下
                { x: rect.left, y: rect.top + rect.height } // 左下
            ];
        });

        // 将canvas坐标转换为图像坐标
        let bboxes_image = bboxes.map(points => getImageCoords(this.image, points));

        // 将点数组转换为[left, top, width, height]格式，并保留两位小数
        bboxes_image = bboxes_image.map(points => {
            let left = parseFloat(points[0].x.toFixed(2));
            let top = parseFloat(points[0].y.toFixed(2));
            let width = parseFloat((points[1].x - points[0].x).toFixed(2));
            let height = parseFloat((points[3].y - points[0].y).toFixed(2));
            return { left, top, width, height };
        });

        return bboxes_image;
    }
}
